home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / OpenGL / stonehenge / Point.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.9 KB  |  403 lines

  1. /*
  2.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED 
  4.  * Permission to use, copy, modify, and distribute this software for 
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that 
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission. 
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  * 
  25.  * US Government Users Restricted Rights 
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37. #ifndef POINT_H
  38. #define POINT_H
  39.  
  40. #ifndef POINT_EXTERN
  41. #define POINT_EXTERN extern
  42. #endif 
  43.  
  44. #include <math.h>
  45.  
  46. const float point_fudge = .000001;
  47.  
  48. class Point {
  49.  public:
  50.   inline Point operator=(Point a);
  51.   inline Point operator=(GLfloat *a);
  52.   inline Point operator+(Point a);
  53.   inline Point operator+=(Point a);
  54.   inline Point operator-(Point a);
  55.   // This takes a cross-product
  56.   inline Point operator*(Point b);
  57.   inline Point operator*(GLfloat b);
  58.   inline Point operator*=(GLfloat b);
  59.   inline Point operator/(GLfloat b);
  60.   inline Point operator/=(GLfloat b);
  61.   inline GLfloat& operator[](int index);
  62.   
  63.   inline void set(GLfloat x, GLfloat y, GLfloat z, GLfloat w = 1.0);
  64.   
  65.   inline GLfloat dist(Point b);
  66.   inline GLfloat dot(Point b);
  67.   inline GLfloat dot(GLfloat x, GLfloat y, GLfloat z);
  68.   inline GLfloat mag();
  69.   inline GLfloat magsquared();
  70.   inline Point unit();
  71.   inline void unitize();
  72.   
  73.   inline Point scale(Point p);
  74.   
  75.   // Angle is in RADIANS
  76.   inline Point rotate(Point axis, GLfloat angle);
  77.   inline Point rotate(Point axis, GLfloat c, GLfloat s);
  78.   inline void rotate_self(Point axis, GLfloat c, GLfloat s);
  79.   Point rotate_abouty(GLfloat c, GLfloat s);
  80.   Point rotate_aboutz(GLfloat c, GLfloat s);
  81.   
  82.   // Returns point projected through proj_pt into XY plane
  83.   // Does nothing if proj_pt - *this is parallel to XY plane
  84.   inline Point project(Point proj_pt);
  85.   inline void project_self(Point proj_pt);
  86.   inline void Point::project_self(GLfloat px, GLfloat py, GLfloat pz);
  87.   inline Point project_direction(Point direction);
  88.   inline Point Point::project_direction(GLfloat x, GLfloat y, GLfloat z);
  89.   // This projects (px, py, pz) into this in direction (dx, dy, dz)
  90.   inline void Point::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
  91.                      GLfloat x, GLfloat y, GLfloat z);
  92.  
  93.   // Returns point projected through light and refracted into XY
  94.   // plane.  
  95.   // N is normal at point (ie normal at *this)
  96.   // I is the index of refraction
  97.   inline Point refract(Point light, Point N, GLfloat I);
  98.   void refract_self(Point light, Point N, GLfloat I);
  99.   Point refract_direction(Point light, Point N, GLfloat I);
  100.   
  101.   inline void glvertex();
  102.   inline void glnormal();
  103.   
  104.   void print();
  105.   void print(const char *format);
  106.   
  107.   GLfloat pt[4];
  108.  private:
  109. };
  110.  
  111. POINT_EXTERN Point val;
  112.  
  113. #define DOT(a, b) (a.pt[0]*b.pt[0] + a.pt[1]*b.pt[1] + a.pt[2]*b.pt[2])
  114. #define THIS_DOT(b) (pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2])
  115.  
  116. inline Point Point::operator=(Point a)
  117. {
  118.   pt[0] = a.pt[0];
  119.   pt[1] = a.pt[1];
  120.   pt[2] = a.pt[2];
  121.   pt[3] = a.pt[3];
  122.   return *this;
  123. }
  124.  
  125. inline Point Point::operator=(GLfloat *a)
  126. {
  127.   pt[0] = a[0]; 
  128.   pt[1] = a[1]; 
  129.   pt[2] = a[2]; 
  130.   pt[3] = 1;
  131.   return *this;
  132. }
  133.  
  134. inline Point Point::operator+(Point a)
  135. {  
  136.   val.pt[0] = pt[0] + a.pt[0];
  137.   val.pt[1] = pt[1] + a.pt[1];
  138.   val.pt[2] = pt[2] + a.pt[2]; 
  139.   return val; 
  140. }
  141.  
  142. inline Point Point::operator+=(Point a)
  143. {
  144.   pt[0] += a.pt[0];
  145.   pt[1] += a.pt[1];
  146.   pt[2] += a.pt[2];
  147.   return *this;
  148. }
  149.  
  150. inline Point Point::operator-(Point a)
  151. {
  152.   val.pt[0] = pt[0] - a.pt[0];
  153.   val.pt[1] = pt[1] - a.pt[1];
  154.   val.pt[2] = pt[2] - a.pt[2];
  155.   return val;
  156. }
  157.   
  158. inline Point Point::operator*(Point b)
  159. {
  160.   val.pt[0] = pt[1]*b.pt[2] - b.pt[1]*pt[2];
  161.   val.pt[1] = pt[2]*b.pt[0] - b.pt[2]*pt[0];
  162.   val.pt[2] = pt[0]*b.pt[1] - pt[1]*b.pt[0];
  163.   return val;
  164. }
  165.  
  166. inline Point Point::operator*(GLfloat b)
  167. {
  168.   val.pt[0] = pt[0] * b;
  169.   val.pt[1] = pt[1] * b;
  170.   val.pt[2] = pt[2] * b;
  171.   return val;
  172. }
  173.  
  174. inline Point Point::operator*=(GLfloat b)
  175. {
  176.   pt[0] *= b;
  177.   pt[1] *= b;
  178.   pt[2] *= b;
  179.   return *this;
  180. }
  181.  
  182. inline Point Point::operator/(GLfloat b)
  183. {
  184.   val.pt[0] = pt[0] / b;
  185.   val.pt[1] = pt[1] / b;
  186.   val.pt[2] = pt[2] / b;
  187.   return val;
  188. }
  189.  
  190. inline Point Point::operator/=(GLfloat b)
  191. {
  192.   pt[0] /= b;
  193.   pt[1] /= b;
  194.   pt[2] /= b;
  195.   return *this;
  196. }
  197.  
  198. inline GLfloat& Point::operator[](int index)
  199. {
  200.   return pt[index];
  201. }
  202.  
  203. inline void Point::set(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  204. {
  205.   pt[0] = x;
  206.   pt[1] = y;
  207.   pt[2] = z;
  208.   pt[3] = w;
  209. }
  210.  
  211. inline GLfloat Point::dist(Point b)
  212. {
  213.   return (*this - b).mag();
  214. }
  215.  
  216. inline GLfloat Point::dot(Point b)
  217. {
  218.   return pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2];
  219. }
  220.  
  221. inline GLfloat Point::dot(GLfloat x, GLfloat y, GLfloat z)
  222.   return pt[0]*x + pt[1]*y + pt[2]*z;
  223. }
  224.  
  225. inline GLfloat Point::mag()
  226. {
  227.   return sqrt(pt[0]*pt[0] + pt[1]*pt[1] + 
  228.               pt[2]*pt[2]);
  229. }
  230.  
  231. inline GLfloat Point::magsquared()
  232. {
  233.   return pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2];
  234. }
  235.  
  236. inline Point Point::unit()
  237. {
  238.   GLfloat m = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]);
  239.   val.pt[0] = pt[0] / m;
  240.   val.pt[1] = pt[1] / m;
  241.   val.pt[2] = pt[2] / m;
  242.   return val;
  243. }
  244.  
  245. inline void Point::unitize()
  246. {
  247.   GLfloat m = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]);
  248.   pt[0] /= m;
  249.   pt[1] /= m;
  250.   pt[2] /= m;
  251. }
  252.  
  253. inline Point Point::scale(Point p) 
  254. {
  255.   val.pt[0] = pt[0] * p.pt[0];
  256.   val.pt[1] = pt[1] * p.pt[1];
  257.   val.pt[2] = pt[2] * p.pt[2];
  258.   return val;
  259. }
  260.  
  261. inline Point Point::rotate(Point axis, GLfloat angle)
  262. {
  263.   return rotate(axis, cos(angle), sin(angle));
  264. }
  265.  
  266. inline Point Point::rotate(Point axis, GLfloat c, GLfloat s)
  267. {
  268.   float x = axis.pt[0], y = axis.pt[1], z = axis.pt[2], t = 1.0 - c;
  269.   float tx, ty;
  270.   
  271.   tx = t*x;
  272.   /* Taking advantage of inside info that this is a common case */
  273.   if (y == 0.0) {
  274.     val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(-s*z) + pt[2]*(tx*z);
  275.     val.pt[1] = pt[0]*(s*z) + pt[1]*c + pt[2]*(-s*x);
  276.     val.pt[2] = pt[0]*(tx*z) + pt[1]*s*x + pt[2]*(t*z*z + c);
  277.   } else {
  278.     ty = t*y;
  279.     val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(tx*y - s*z) +
  280.       pt[2]*(tx*z + s*y);
  281.     val.pt[1] = pt[0]*(tx*y + s*z) + pt[1]*(ty*y + c) +
  282.       pt[2]*(ty*z - s*x);
  283.     val.pt[2] = pt[0]*(tx*z - s*y) + pt[1]*(ty*z + s*x) +
  284.       pt[2]*(t*z*z + c);
  285.   }
  286.   return val;
  287. }
  288.  
  289. inline void Point::rotate_self(Point axis, GLfloat c, GLfloat s)
  290. {
  291.   float Px, Py, Pz;
  292.   float x = axis.pt[0], y = axis.pt[1], z = axis.pt[2], t = 1.0 - c;
  293.   float tx, ty;
  294.   
  295.   tx = t*x;
  296.   Px = pt[0];
  297.   Py = pt[1];
  298.   Pz = pt[2];
  299.   /* Taking advantage of inside info that this is a common case */
  300.   if (!y) {
  301.     pt[0] = Px*(tx*x + c) +    Py*(-s*z) +     Pz*(tx*z);
  302.     pt[1] = Px*(s*z) +         Py*c +         Pz*(-s*x);
  303.     pt[2] = Px*(tx*z) +     Py*s*x +     Pz*(t*z*z + c);
  304.   } else {
  305.     ty = t*y;
  306.     pt[0] = Px*(tx*x + c) +     Py*(tx*y - s*z) +
  307.       Pz*(tx*z + s*y);
  308.     pt[1] = Px*(tx*y + s*z) +     Py*(ty*y + c) +
  309.       Pz*(ty*z - s*x);
  310.     pt[2] = Px*(tx*z - s*y) +     Py*(ty*z + s*x) +
  311.       Pz*(t*z*z + c);
  312.   }
  313. }  
  314.  
  315. inline void Point::glvertex() 
  316. {
  317.   glVertex3fv(pt);
  318. }
  319.  
  320. inline void Point::glnormal()
  321. {
  322.   glNormal3fv(pt);
  323. }
  324.  
  325. inline Point Point::project(Point proj_pt)
  326. {
  327.   GLfloat dirx = pt[0] - proj_pt.pt[0], 
  328.       diry = pt[1] - proj_pt.pt[1],
  329.       dirz = pt[2] - proj_pt.pt[2];
  330.   GLfloat t;
  331.  
  332.   if (fabs(dirz) < point_fudge) val = *this;
  333.   else {
  334.     t = -proj_pt.pt[2] / dirz;
  335.     val.pt[0] = proj_pt.pt[0] + dirx*t;
  336.     val.pt[1] = proj_pt.pt[1] + diry*t;
  337.     val.pt[2] = 0.0;
  338.   }
  339.   return val;
  340. }
  341.  
  342. // This naively assumes that proj_pt[z] != this->pt[z]
  343. inline void Point::project_self(Point proj_pt)
  344. {
  345.   GLfloat dirx = pt[0] - proj_pt.pt[0], 
  346.       diry = pt[1] - proj_pt.pt[1],
  347.       dirz = pt[2] - proj_pt.pt[2];
  348.   GLfloat t;
  349.  
  350.   t = -proj_pt.pt[2] / dirz;
  351.   pt[0] = proj_pt.pt[0] + dirx*t;
  352.   pt[1] = proj_pt.pt[1] + diry*t;
  353.   pt[2] = 0.0;
  354. }
  355.  
  356. inline void Point::project_self(GLfloat px, GLfloat py, GLfloat pz)
  357. {
  358.   GLfloat dirx = pt[0] - px, 
  359.   diry = pt[1] - py,
  360.   dirz = pt[2] - pz, t;
  361.  
  362.   t = -pz / dirz;
  363.   pt[0] = px + dirx*t;
  364.   pt[1] = py + diry*t;
  365.   pt[2] = 0.0;
  366. }
  367.  
  368. inline Point Point::project_direction(Point direction) {
  369.   GLfloat t;
  370.  
  371.   t = -pt[2] / direction.pt[2];
  372.   val.pt[0] = pt[0] + direction.pt[0]*t;
  373.   val.pt[1] = pt[1] + direction.pt[1]*t;
  374.   val.pt[2] = 0;
  375.   return val;
  376. }
  377.  
  378. inline Point Point::project_direction(GLfloat x, GLfloat y, GLfloat z) 
  379. {
  380.   GLfloat t;
  381.  
  382.   t = -pt[2] / z;
  383.   val.pt[0] = pt[0] + x*t;
  384.   val.pt[1] = pt[1] + y*t;
  385.   val.pt[2] = 0;
  386.   return val;
  387. }
  388.  
  389. inline void Point::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
  390.                      GLfloat dx, GLfloat dy, GLfloat dz)
  391. {
  392.   GLfloat t = -pz / dz;
  393.   pt[0] = px + dx*t;
  394.   pt[1] = py + dy*t;
  395.   pt[2] = 0;
  396. }
  397.  
  398.  
  399. #undef POINT_EXTERN
  400.  
  401. #endif
  402.